/*
 *    Copyright 2009-2023 the original author or authors.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       https://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package org.apache.ibatis.ryan.builder;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.jdbc.SQL;
import org.apache.ibatis.ryan.Tools;

/**
 * delete 语句构建
 */
public class DeleteBuilder<E> implements Builder<E> {
  /**
   * param2 删除语句构建固定参数名称
   * 根据 SProviderc.class 的方法来的 是第二个参数
   */
  public static String param2 = "param2";
  /**
   * mybatis sql对象
   */
  private SQL sql = new SQL();
  /**
   * 表名
   */
  private String from;
  /**
   * 参数键值对
   */
  private Map<String, Object> params = new HashMap<>();

  /**
   * 获取sql语句执行返回类型-查询用到
   */
  @Override
  public Class<E> getResultType() {
    return null;
  }

  public String getSql() {
    return sql.toString();
  }

  private DeleteBuilder(String table) {
    from = Tools.toUnderLine(table);
  }

  public static DeleteBuilder<?> build(String table) {
    // 初始化设置表名
    DeleteBuilder<?> criteriaQuery = new DeleteBuilder<>(table);
    criteriaQuery.init();
    return criteriaQuery;
  }

  /**
   * 构建delete from
   */
  private void init() {
    sql.DELETE_FROM(from);
  }

  public Map<String, Object> getParams() {
    return params;
  }

  public DeleteBuilder<?> whereEq(String propName, Object value) {
    return where(Tools.eq, propName, value);
  }

  /**
   * 拼接 where 条件
   *
   * @param op
   *          条件模板 eq = "%s = #{%s.%s}"
   * @param propName
   *          字段名称
   * @param value
   *          条件值
   *
   * @return
   */
  private DeleteBuilder<?> where(String op, String propName, Object value) {
    value = Tools.formatIfDate(value);
    // 查询条件列名
    String colName = Tools.toUnderLine(propName);
    // 查询条件参数名称
    String sqlVarName = Tools.buildVarName("where_" + colName);
    // "id = #{param2.where_id}"
    sql.WHERE(String.format(op, colName, param2, sqlVarName));
    params.put(sqlVarName, value);
    return this;
  }

  /**
   * like 条件拼接
   *
   * @param propName
   * @param value
   *
   * @return
   */
  public DeleteBuilder<?> whereLike(String propName, String value) {
    return where(Tools.like, propName, value);
  }

  /**
   * 小于 条件拼接
   *
   * @param propName
   * @param value
   *
   * @return
   */
  public DeleteBuilder<?> whereLow(String propName, Object value) {
    return where(Tools.low, propName, value);
  }

  /**
   * 小于等于 条件
   *
   * @param propName
   * @param value
   *
   * @return
   */
  public DeleteBuilder<?> whereLowEq(String propName, Object value) {
    return where(Tools.lowEq, propName, value);
  }

  /**
   * in条件
   *
   * @param propName
   * @param value
   *
   * @return
   */
  public DeleteBuilder<?> whereIn(String propName, List<Object> value) {
    if (value.isEmpty()) {
      return this;
    } else {
      Tools.staticWhereIn(propName, param2, value, sql, params);
      return this;
    }
  }

  /**
   * 大于条件
   *
   * @param propName
   * @param value
   *
   * @return
   */
  public DeleteBuilder<?> whereBig(String propName, Object value) {
    return where(Tools.big, propName, value);
  }

  /**
   * 大于等于条件
   *
   * @param propName
   * @param value
   *
   * @return
   */
  public DeleteBuilder<?> whereBigEq(String propName, Object value) {
    return where(Tools.bigEq, propName, value);
  }

  /**
   * 传入实体根据 实体字段不为空的字段拼接删除SQL
   *
   * @param <Bean>
   * @param bean
   *
   * @return
   */
  public <Bean> DeleteBuilder<?> whereBean(Bean bean) {
    return whereBean(bean, Tools.tableName(bean.getClass()));
  }

  /**
   * 传入实体根据 实体类型的字段拼接删除SQL
   *
   * @param <Bean>
   * @param bean
   *
   * @return
   */
  public <Bean> DeleteBuilder<?> whereBeanAll(Bean bean) {
    return whereBeanAll(bean, Tools.tableName(bean.getClass()));
  }

  /**
   * 根据传入的对象，不为空的字段都拼接成where条件
   *
   * @param <Bean>
   *          类型
   * @param bean
   * @param table
   *
   * @return
   */
  public <Bean> DeleteBuilder<?> whereBean(Bean bean, String table) {
    List<Field> fields = Tools.getInstanceFields(bean.getClass());
    if (fields.isEmpty()) {
      return this;
    } else {
      fields.forEach((field) -> {
        Object fieldValue = Tools.getFieldValue(bean, field);
        if (fieldValue != null) {
          String pre = table != null ? table : Tools.tableName(bean.getClass());
          whereEq(pre + "." + field.getName(), fieldValue);
        }
      });
      return this;
    }
  }

  public <Bean> DeleteBuilder<?> whereBeanAll(Bean bean, String table) {
    List<Field> fields = Tools.getInstanceFields(bean.getClass());
    if (fields.isEmpty()) {
      return this;
    } else {
      fields.forEach((field) -> {
        Object fieldValue = Tools.getFieldValue(bean, field);
        String pre = table != null ? table : Tools.tableName(bean.getClass());
        whereEq(pre + "." + field.getName(), fieldValue);
      });
      return this;
    }
  }

  /**
   * 多表join
   *
   * @param table2
   *          eg: user
   * @param table2ColumnOn2
   *          user.id
   * @param table1ColumnOn
   *          dept.user_id
   *
   * @return
   */
  public DeleteBuilder<?> joinOn(String table2, String table2ColumnOn2, String table1ColumnOn) {
    String format = String.format(" %s on %s = %s ", Tools.toUnderLine(table2), Tools.toUnderLine(table2ColumnOn2),
        Tools.toUnderLine(table1ColumnOn));
    sql.INNER_JOIN(format);
    return this;
  }
}
